package com.wss.common.widget;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.ScrollView;
import ohos.agp.components.element.Element;
import ohos.app.Context;

import java.util.ArrayList;
import java.util.List;

/**
 * TODO Describe：滑动粘性ScrollView，设置View的tag = sticky 滑动可吸顶
 * Created by 吴天强 on 2020/05/13.
 * Copy from: https://github.com/LidongWen/MultiTypeAdapter
 */
public class StickyNavLayout extends ScrollView implements
        ComponentContainer.ArrangeListener {

    public interface OnViewStickyListener {

        void onSticky(Component view);

        void onUnSticky(Component view);
    }

    /**
     * Tag for views that should stick and have constant drawing. e.g. TextViews, ImageViews etc
     */
    public static final String STICKY_TAG = "sticky";
    /**
     * Flag for views that should stick and have non-constant drawing. e.g. Buttons, ProgressBars etc
     */
    public static final String FLAG_NONCONSTANT = "-nonconstant";
    /**
     * Flag for views that have aren't fully opaque
     */
    public static final String FLAG_HASTRANSPARENCY = "-hastransparency";
    /**
     * Default height of the shadow peeking out below the stuck view.
     */
    private static final int DEFAULT_SHADOW_HEIGHT = 10; // dp;
    private ArrayList<Component> stickyViews;
    private Component currentlyStickingView;
    private float stickyViewTopOffset;
    private final Runnable invalidateRunnable = new Runnable() {
        @Override
        public void run() {
            if (currentlyStickingView != null) {
                int l = getLeftForViewRelativeOnlyChild(currentlyStickingView);
                int t = getBottomForViewRelativeOnlyChild(currentlyStickingView);
                int r = getRightForViewRelativeOnlyChild(currentlyStickingView);
                //TODO 更新布局
//                int b = (int) (getScrollY() + (currentlyStickingView.getHeight() + stickyViewTopOffset));
//                invalidate(l, t, r, b);
            }
            //TODO 延迟post delayed
//            postDelayed(this, 16);
        }
    };
    private int stickyViewLeftOffset;
    private boolean redirectTouchesToStickyView;
    private boolean clippingToPadding;
    private boolean clipToPaddingHasBeenSet;
    private int mShadowHeight = DEFAULT_SHADOW_HEIGHT;
    private Element mShadowDrawable;
    private boolean hasNotDoneActionDown = true;

    private List<OnViewStickyListener> mOnViewStickyListeners;

    public StickyNavLayout(Context context) {
        this(context, null);
    }

    public StickyNavLayout(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public StickyNavLayout(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        setArrangeListener(this);
    }

    public void addOnViewStickyListener(OnViewStickyListener stickyListener) {
        if (mOnViewStickyListeners == null)
            mOnViewStickyListeners = new ArrayList<>();
        mOnViewStickyListeners.add(stickyListener);
    }

    public void removeOnViewStickyListener(OnViewStickyListener stickyListener) {
        if (mOnViewStickyListeners != null)
            mOnViewStickyListeners.remove(stickyListener);
    }

    public void clearOnViewStickyListener() {
        if (mOnViewStickyListeners != null)
            mOnViewStickyListeners.clear();
    }

    public void setShadowHeight(int height) {
        mShadowHeight = height;
    }

    public void setShadowDrawable(Element shadowDrawable) {
        mShadowDrawable = shadowDrawable;
    }

    public void setup() {
        stickyViews = new ArrayList<>();
    }

    private int getLeftForViewRelativeOnlyChild(Component v) {
        int left = v.getLeft();
        while (v.getComponentParent()
                != null && v.getComponentParent()
                != getComponentAt(0)) {
            v = (Component) v.getComponentParent();
            left += v.getLeft();
        }
        return left;
    }

    private int getTopForViewRelativeOnlyChild(Component v) {
        int top = v.getTop();
        while (v.getComponentParent()
                != null && v.getComponentParent()
                != getComponentAt(0)) {
            v = (Component) v.getComponentParent();
            top += v.getTop();
        }
        return top;
    }

    private int getRightForViewRelativeOnlyChild(Component v) {
        int right = v.getRight();
        while (v.getComponentParent()
                != null && v.getComponentParent()
                != getComponentAt(0)) {
            v = (Component) v.getComponentParent();
            right += v.getRight();
        }
        return right;
    }

    private int getBottomForViewRelativeOnlyChild(Component v) {
        int bottom = v.getBottom();
        while (v.getComponentParent()
                != null && v.getComponentParent()
                != getComponentAt(0)) {
            v = (Component) v.getComponentParent();
            bottom += v.getBottom();
        }
        return bottom;
    }

    @Override
    public boolean onArrange(int left, int top, int width, int height) {
        return true;
    }

    public void setClippingToPadding(boolean clippingToPadding) {
        this.clippingToPadding = clippingToPadding;
    }

}
